"""
数据模型定义
包含所有API请求和响应的Pydantic模型
"""

from typing import List, Optional, Dict, Any
from pydantic import BaseModel, Field, validator
from enum import IntEnum, Enum
import numpy as np

# ======================= 状态码枚举 =======================

class StatusCode(IntEnum):
    """API状态码枚举"""
    SUCCESS = 100
    NOT_FOUND = 101
    INTERNAL_SERVER_ERROR = 102

class TaskStatus(str, Enum):
    """任务状态枚举"""
    PENDING = "pending"
    RUNNING = "running"
    COMPLETED = "completed"
    FAILED = "failed"

# ======================= 请求模型 =======================
class AnalysisRequest(BaseModel):
    """单个AI分析请求模型"""
    dicom_uid: str = Field(
        ..., 
        description="DICOM文件唯一标识符",
        min_length=1,
        max_length=64,
        example="1.123.12345.12345.12345.12345"
    )
    # 使用 .tolist() 将 numpy 数组转换为原生 Python 列表，避免 OpenAPI 生成时的序列化错误
    img_data: Optional[List[List[int]]] = Field(
        ...,
        description="图像数据(尺寸为512x512)"
    )
    # 修复BUG：Pydantic 在生成 OpenAPI Schema 时无法序列化 numpy.ndarray，这里需转换为列表
    seg_data: Optional[List[List[int]]] = Field(
        ...,
        description="分割数据(尺寸为512x512)"
    )
    dsa_position: str = Field(
        ...,
        description="DSA造影位置 (F/LS/RCA)",
        example="F"
    )
    
    @validator('img_data')
    def validate_img_data_size(cls, v):
        """验证图像数据尺寸必须为512x512"""
        if v is None or v == []:
            raise ValueError('图像数据不能为空')
        
        if len(v) != 512:
            raise ValueError('图像数据行数必须为512')
        
        for row_idx, row in enumerate(v):
            if not isinstance(row, list):
                raise ValueError(f'图像数据第{row_idx + 1}行必须是列表')
            if len(row) != 512:
                raise ValueError(f'图像数据第{row_idx + 1}行列数必须为512，当前为{len(row)}')
        
        return v
    
    @validator('seg_data')
    def validate_seg_data_size(cls, v):
        """验证分割数据尺寸必须为512x512"""
        if v is None or v == []:
            raise ValueError('分割数据不能为空')
        
        if len(v) != 512:
            raise ValueError('分割数据行数必须为512')
        
        for row_idx, row in enumerate(v):
            if not isinstance(row, list):
                raise ValueError(f'分割数据第{row_idx + 1}行必须是列表')
            if len(row) != 512:
                raise ValueError(f'分割数据第{row_idx + 1}行列数必须为512，当前为{len(row)}')
        
        return v
    
    @validator('dicom_uid')
    def validate_dicom_uid(cls, v):
        """验证DICOM UID不能为空"""
        if not v or not v.strip():
            raise ValueError('DICOM UID不能为空')
        return v.strip()
    
    @validator('dsa_position')
    def validate_dsa_position(cls, v):
        """验证DSA位置值"""
        valid_positions = ['F', 'LS', 'RCA']
        if v not in valid_positions:
            raise ValueError(f'DSA位置必须是以下值之一: {valid_positions}')
        return v
    
class ImageRequest(BaseModel):
    """图像请求模型"""
    image_uid: str = Field(..., description="图像文件唯一标识符")
    image_data: str = Field(..., description="图像数据(尺寸为512x512x3)")
    
    @validator('image_uid')
    def validate_image_uid(cls, v):
        """验证图像UID不能为空"""
        if not v or not v.strip():
            raise ValueError('图像UID不能为空')
        return v.strip()
    
    @validator('image_data')
    def validate_image_data(cls, v):
        """验证图像数据不能为空"""
        if not v or not v.strip():
            raise ValueError('图像数据不能为空')
        return v.strip()

# ======================= 响应模型 =======================
        
class AnalysisResponse(BaseModel):
    """分析结果响应模型"""
    dicom_uid: str = Field(..., description="DICOM文件UID")
    processing_time: float = Field(..., description="处理时间(秒)")
    result: Dict[str, Any] = Field(..., description="AI分析结果")
    status_code: int = Field(
        default=StatusCode.SUCCESS,
        description="HTTP状态码"
    )
    
    @validator('status_code')
    def validate_status_code(cls, v):
        """验证状态码是否有效"""
        valid_codes = [code.value for code in StatusCode]
        if v not in valid_codes:
            raise ValueError(f'状态码必须是以下值之一: {valid_codes}')
        return v

class TaskCreateResponse(BaseModel):
    """任务创建响应模型"""
    task_id: str = Field(..., description="任务唯一标识符")
    status: TaskStatus = Field(
        default=TaskStatus.PENDING, 
        description="任务状态"
    )
    created_at: str = Field(..., description="创建时间")
    status_code: int = Field(
        default=StatusCode.SUCCESS,
        description="HTTP状态码"
    )
    
    @validator('status_code')
    def validate_status_code(cls, v):
        """验证状态码是否有效"""
        valid_codes = [code.value for code in StatusCode]
        if v not in valid_codes:
            raise ValueError(f'状态码必须是以下值之一: {valid_codes}')
        return v
    
class TaskResultResponse(BaseModel):
    """任务响应模型"""
    task_id: str = Field(..., description="任务唯一标识符")
    status: TaskStatus = Field(..., description="任务状态")
    created_at: Optional[str] = Field(default=None, description="创建时间")
    finished_at: Optional[str] = Field(default=None, description="完成时间")
    dicom_uid: Optional[str] = Field(default=None, description="DICOM文件UID")
    result: Optional[Dict[str, Any]] = Field(default=None, description="AI分析结果")
    error: Optional[str] = Field(default=None, description="错误信息")
    status_code: int = Field(
        default=StatusCode.SUCCESS,
        description="HTTP状态码"
    )
    
    @validator('status_code')
    def validate_status_code(cls, v):
        """验证状态码是否有效"""
        valid_codes = [code.value for code in StatusCode]
        if v not in valid_codes:
            raise ValueError(f'状态码必须是以下值之一: {valid_codes}')
        return v
    
    @validator('status_code', pre=False, always=True)
    def set_status_code_based_on_task_status(cls, v, values):
        """根据任务状态自动设置状态码"""
        if 'status' in values:
            task_status = values['status']
            if task_status == TaskStatus.COMPLETED:
                return StatusCode.SUCCESS
            elif task_status == TaskStatus.FAILED:
                return StatusCode.INTERNAL_SERVER_ERROR
            elif task_status in [TaskStatus.PENDING, TaskStatus.RUNNING]:
                return StatusCode.SUCCESS
        return v

class ErrorResponse(BaseModel):
    """错误响应模型"""
    task_id: str = Field(..., description="任务唯一标识符")
    error: str = Field(..., description="错误信息")
    status_code: int = Field(
        default=StatusCode.INTERNAL_SERVER_ERROR.value,
        description="HTTP状态码"
    )

class TaskListResponse(BaseModel):
    """任务列表响应模型"""
    task_list: List[Dict[str, Any]] = Field(..., description="任务列表")
    status_code: int = Field(
        default=StatusCode.SUCCESS,
        description="HTTP状态码"
    )
    
    